import { ExtendRuleItem } from 'jn-ve-global'

export const getRequiredRule = (type: string): ExtendRuleItem => {
    return {
        required: true,
        message: type === 'input' ? '请输入' : '请选择'
    }
}

export const validateUrl = (rule, value, callback) => {
    if (value === '' || value === undefined || value === null) {
        callback()
    } else {
        const reg = /^(https?:\/\/)?(www\.)?([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,}(:\d{1,5})?(\/\S*)?$/
        if (!reg.test(value)) {
            callback(new Error('请输入正确的url'))
        } else {
            callback()
        }
    }
}

// 输入不小于0的数，且最多保留N位小数
export const limitDecimal = (value, number1, number2, callback) => {
    if (value === '' || value === undefined || value === null) {
        callback()
    }
    setTimeout(() => {
        const str = `${value}`
        if (str === '' || str === undefined || str === null) return callback()
        const reg = /^\d+$|^\d*\.\d+$/g
        if (!reg.test(str)) {
            return callback(new Error('请输入不小于0的数'))
        }
        if (str.length > 17) {
            return callback(new Error('输入最多16位'))
        }

        const strArr = str.split('.')
        if (strArr[0].length > number1) {
            return callback(new Error(`整数位最多${number1}位`))
        }
        if (str.includes('.')) {
            // const decimal = stringValue.split('.')[1]
            if (strArr[1].length > number2) {
                return callback(new Error(`最多保留${number2}位小数`))
            }
        }

        callback()
    }, 0)
}

/*是否合法IP地址*/
export const validateIP = (rule, value, callback) => {
    if (value === '' || value === undefined || value === null) {
        callback()
    } else {
        const reg =
            /^(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])\.(\d{1,2}|1\d\d|2[0-4]\d|25[0-5])$/
        if (!reg.test(value) && value !== '') {
            callback(new Error('请输入正确的IP地址'))
        } else {
            callback()
        }
    }
}

/* 是否手机号码或者固话
* 规则说明：
1、可以是1开头的11位数字（手机号）
2、可以是“区号-电话号-分机号”或者是“(区号)电话号-分机号”格式
3、区号是0开头的3～4位数字，可以没有区号
4、电话号是5～8位数字，不能以0开头
5、分机号是1～8位数字，可以没有分机号*/
export const validatePhoneTwo = (rule, value, callback) => {
    // if (value === '' || value === undefined || value === null) {
    //     return callback(new Error('请输入联系方式'))
    // }
    if (value === '' || value === undefined || value === null) {
        callback()
    }
    const reg = /^1\d{10}$|^(0\d{2,3}-?|\(0\d{2,3}\))?[1-9]\d{4,7}(-\d{1,8})?$/
    if (value === '' || value === undefined || value === null) {
        callback()
    } else {
        if (!reg.test(value) && value !== '') {
            callback(new Error('请输入正确的电话号码或者固话号码'))
        } else {
            callback()
        }
    }
}
/* 是否固话*/
export const validateTelphone = (rule, value, callback) => {
    const reg = /0\d{2,3}-?\d{7,8}/
    if (value === '' || value === undefined || value === null) {
        callback()
    } else if (!reg.test(value) && value !== '') {
        callback(new Error('请输入正确的固话（格式：区号+号码,如010-1234567）'))
    } else {
        callback()
    }
}
/* 是否手机号码*/
export const validatePhone = (rule, value, callback) => {
    if (value === '' || value === undefined || value === null) {
        return callback(new Error('请输入联系方式'))
    }
    const reg = /^[1][3,4,5,6,7,8,9][0-9]{9}$/
    if (value === '' || value === undefined || value === null) {
        callback()
    } else if (!reg.test(value) && value !== '') {
        callback(new Error('请输入正确的手机格式'))
    } else {
        callback()
    }
}
/* 是否手机号码,非必填*/
export const validatePhoneNoMust = (rule, value, callback) => {
    const reg = /^[1][3,4,5,7,8,9][0-9]{9}$/
    if (value === '' || value === undefined || value === null) {
        callback()
    } else if (!reg.test(value) && value !== '') {
        callback(new Error('请输入正确的手机格式'))
    } else {
        callback()
    }
}
/* 是否身份证号码*/
export const IDCard = (val) => {
    var area = {
        11: '北京',
        12: '天津',
        13: '河北',
        14: '山西',
        15: '内蒙古',
        21: '辽宁',
        22: '吉林',
        23: '黑龙江',
        31: '上海',
        32: '江苏',
        33: '浙江',
        34: '安徽',
        35: '福建',
        36: '江西',
        37: '山东',
        41: '河南',
        42: '湖北',
        43: '湖南',
        44: '广东',
        45: '广西',
        46: '海南',
        50: '重庆',
        51: '四川',
        52: '贵州',
        53: '云南',
        54: '西藏',
        61: '陕西',
        62: '甘肃',
        63: '青海',
        64: '宁夏',
        65: '新疆',
        71: '台湾',
        81: '香港',
        82: '澳门',
        91: '国外'
    }
    var Y, JYM
    var S, M
    // console.log(val)
    var idcard_array = new Array()
    idcard_array = val.split('')
    var reg
    // 地区检验
    if (area[parseInt(val.substr(0, 2))] === null) {
        // this.IDCardText = "身份证号码地区非法！";
        return false
    }
    // 身份号码位数及格式检验
    switch (val.length) {
    case 15:
        if (
            (parseInt(val.substr(6, 2)) + 1900) % 4 === 0 ||
                ((parseInt(val.substr(6, 2)) + 1900) % 100 === 0 &&
                    (parseInt(val.substr(6, 2)) + 1900) % 4 === 0)
        ) {
            reg =
                    /^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}$/ // 测试出生日期的合法性
        } else {
            reg =
                    /^[1-9][0-9]{5}[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}$/ // 测试出生日期的合法性
        }
        if (reg.test(val)) return true
        else {
            return false
        }
    case 18:
        // 18位身份号码检测
        // 出生日期的合法性检查
        // 闰年月日:((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))
        // 平年月日:((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))
        if (
            parseInt(val.substr(6, 4)) % 4 === 0 ||
                (parseInt(val.substr(6, 4)) % 100 === 0 && parseInt(val.substr(6, 4)) % 4 === 0)
        ) {
            //reg = /^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$/;// 闰年出生日期的合法性正则表达式
            reg =
                    /^[1-9][0-9]{5}(19|2[0-9])[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|[1-2][0-9]))[0-9]{3}[0-9Xx]$/ // 闰年出生日期的合法性正则表达式
        } else {
            //reg = /^[1-9][0-9]{5}19[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$/;// 平年出生日期的合法性正则表达式
            reg =
                    /^[1-9][0-9]{5}(19|2[0-9])[0-9]{2}((01|03|05|07|08|10|12)(0[1-9]|[1-2][0-9]|3[0-1])|(04|06|09|11)(0[1-9]|[1-2][0-9]|30)|02(0[1-9]|1[0-9]|2[0-8]))[0-9]{3}[0-9Xx]$/ // 平年出生日期的合法性正则表达式
        }
        if (reg.test(val)) {
            // 测试出生日期的合法性
            // 计算校验位
            S =
                    (parseInt(idcard_array[0]) + parseInt(idcard_array[10])) * 7 +
                    (parseInt(idcard_array[1]) + parseInt(idcard_array[11])) * 9 +
                    (parseInt(idcard_array[2]) + parseInt(idcard_array[12])) * 10 +
                    (parseInt(idcard_array[3]) + parseInt(idcard_array[13])) * 5 +
                    (parseInt(idcard_array[4]) + parseInt(idcard_array[14])) * 8 +
                    (parseInt(idcard_array[5]) + parseInt(idcard_array[15])) * 4 +
                    (parseInt(idcard_array[6]) + parseInt(idcard_array[16])) * 2 +
                    parseInt(idcard_array[7]) * 1 +
                    parseInt(idcard_array[8]) * 6 +
                    parseInt(idcard_array[9]) * 3
            Y = S % 11
            M = 'F'
            JYM = '10X98765432'
            M = JYM.substr(Y, 1) // 判断校验位
            // alert(idcard_array[17]);
            if (M === idcard_array[17]) {
                return true // 检测ID的校验位
            } else {
                // this.IDCardText = "身份证号码末位校验位校验出错,请注意X的大小写";
                //						this.IDCardText = "身份证号码末位校验位校验出错！";
                //                     this.IDCardText = "身份证号码末位校验出错！";
                return false
            }
        } else {
            // this.IDCardText = "身份证号码出生日期超出范围！";
            return false
        }
    default:
        // this.IDCardText = "身份证号码位数有误,应该为15位或18位！";
        return false
    }
}
export const validateIdNo = (rule, value, callback) => {
    // const reg =/^[1-9][0-9]{5}(18|19|20)[0-9]{2}((0[1-9])|(10|11|12))(([0-2][1-9])|10|20|30|31)[0-9]{3}([0-9]|(X|x))/
    if (value === '' || value === undefined || value === null) {
        // callback(new Error('请输入身份证号码'))
        callback()
        // } else if (!reg.test(value) && value !== '') {
    } else if (!IDCard(value)) {
        callback(new Error('请输入正确的身份证格式'))
    } else {
        callback()
    }
}

/* 是否社会信用代码*/
export const uniteCreditNo = (val) => {
    // var val = trim(val)
    var val = val?.trim()
    switch (val.length) {
    case 18:
        var reg = /^[0-9A-Z]+$/
        // 18位校验及大写校验
        if (val.length !== 18 || !reg.test(val)) {
            return false
        } else {
            var Ancode // 统一社会信用代码的每一个值
            var Ancodevalue // 统一社会信用代码每一个值的权重
            var total = 0
            var weightedfactors = [
                1, 3, 9, 27, 19, 26, 16, 17, 20, 29, 25, 13, 8, 24, 10, 30, 28
            ] // 加权因子
            var str = '0123456789ABCDEFGHJKLMNPQRTUWXY'
            // 不用I、O、S、V、Z
            for (var i = 0; i < val.length - 1; i++) {
                Ancode = val.substring(i, i + 1)
                Ancodevalue = str.indexOf(Ancode)
                total = total + Ancodevalue * weightedfactors[i]
                // 权重与加权因子相乘之和
            }
            var logiccheckcode = String(31 - (total % 31))

            if (logiccheckcode === '31') {
                logiccheckcode = '0'
            }
            var Str = '0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F,G,H,J,K,L,M,N,P,Q,R,T,U,W,X,Y'
            var Array_Str = Str.split(',')
            logiccheckcode = Array_Str[logiccheckcode]

            var checkcode = val.substring(17, 18)
            if (logiccheckcode !== checkcode) {
                return false
            } else {
                return true
            }
        }
    default:
        return false
    }
}
export const validateSocialCreditNo = (rule, value, callback) => {
    // const reg = /^[0-9A-HJ-NPQRTUWXY]{2}\d{6}[0-9A-HJ-NPQRTUWXY]{10}$/g
    if (value === '' || value === undefined || value === null) {
        // callback(new Error('请输入统一社会信用代码'))
        callback()
        // } else if (!reg.test(value) && value !== '') {
    } else if (!uniteCreditNo(value)) {
        callback(new Error('请输入正确的统一社会信用代码'))
    } else {
        callback()
    }
    callback()
}

/* 是否邮箱*/
export const validateEMail = (rule, value, callback) => {
    // const reg = /^([a-zA-Z0-9]+[-_\.]?)+@[a-zA-Z0-9]+\.[a-z]+$/
    // const reg = /^[A-Za-z0-9\u4e00-\u9fa5]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$/
    const reg =
        /^[A-Za-z\d]+([-_\.][A-Za-z\d]+)*@([A-Za-z\d]+[-\.])+[A-Za-z\d]{2,4}(,[A-Za-z\d]+([-_\.][A-Za-z\d]+)*@([A-Za-z\d]+[-\.])+[A-Za-z\d]{2,4})*$/

    if (value === '' || value === undefined || value === null) {
        callback()
    } else if (!reg.test(value)) {
        callback(new Error('请输入正确的邮箱地址'))
    } else {
        callback()
    }
}
/* 合法uri*/
export const validateURL = (textval) => {
    const urlregex =
        /^(https?|ftp):\/\/([a-zA-Z0-9.-]+(:[a-zA-Z0-9.&%$-]+)*@)*((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|([a-zA-Z0-9-]+\.)*[a-zA-Z0-9-]+\.(com|edu|gov|int|mil|net|org|biz|arpa|info|name|pro|aero|coop|museum|[a-zA-Z]{2}))(:[0-9]+)*(\/($|[a-zA-Z0-9.,?'\\+&%$#=~_-]+))*$/
    return urlregex.test(textval)
}

/*验证内容是否英文数字以及下划线*/
export const isPassword = (rule, value, callback) => {
    const reg = /^[_a-zA-Z0-9]+$/
    if (value === '' || value === undefined || value === null) {
        callback()
    } else if (!reg.test(value)) {
        callback(new Error('密码仅由英文字母，数字以及下划线组成'))
    } else {
        callback()
    }
}

/*自动检验数值的范围*/
export const checkMax = (rule, value, maxValue, callback) => {
    if (value === '' || value === undefined || value === null) {
        callback()
    } else if (!Number(value)) {
        callback(new Error('请输入数字'))
    } else if (value < 1 || value > maxValue) {
        callback(new Error('请输入[1,' + maxValue + ']之间的数字'))
    } else {
        callback()
    }
}
export const checkMin = (rule, value, minValue, callback) => {
    if (value === '' || value === undefined || value === null) {
        callback()
    } else if (!Number(value)) {
        callback(new Error('请输入数字'))
    } else if (value < minValue) {
        callback(new Error('请输入大于' + minValue + '的数字'))
    } else {
        callback()
    }
}

//验证是否1-99之间
export const isOneToNinetyNine = (rule, value, callback) => {
    if (value === '' || value === undefined || value === null) {
        return callback(new Error('输入不可以为空'))
    }
    setTimeout(() => {
        if (!Number(value)) {
            callback(new Error('请输入正整数'))
        } else {
            const re = /^[1-9][0-9]{0,1}$/
            const rsCheck = re.test(value)
            if (!rsCheck) {
                callback(new Error('请输入正整数，值为【1,99】'))
            } else {
                callback()
            }
        }
    }, 0)
}

// 验证是否整数
export const isInteger = (rule, value, callback) => {
    if (value === '' || value === undefined || value === null) {
        return callback(new Error('输入不可以为空'))
    }
    setTimeout(() => {
        if (!Number(value)) {
            callback(new Error('请输入正整数'))
        } else {
            const re = /^[0-9]*[1-9][0-9]*$/
            const rsCheck = re.test(value)
            if (!rsCheck) {
                callback(new Error('请输入正整数'))
            } else {
                callback()
            }
        }
    }, 0)
}

// 验证是否自然数
export const isNaturalNumber = (rule, value, callback) => {
    if (value === '' || value === undefined || value === null) {
        return callback(new Error('输入不可以为空'))
    }
    setTimeout(() => {
        const re = /^(0|[1-9][0-9]*)$/
        const rsCheck = re.test(value)
        if (!rsCheck) {
            callback(new Error('请输入自然数'))
        } else {
            callback()
        }
    }, 0)
}

// 验证是否自然数 非必填
export const isNaturalNumberNoMust = (rule, value, callback) => {
    if (value === '' || value === undefined || value === null) {
        callback()
    }
    setTimeout(() => {
        const re = /^(0|[1-9][0-9]*)$/
        const rsCheck = re.test(value)
        if (!rsCheck) {
            callback(new Error('请输入自然数'))
        } else {
            callback()
        }
    }, 0)
}

// 验证是否整数,非必填
export function isIntegerNotMust(rule, value, callback) {
    if (value === '' || value === undefined || value === null) {
        callback()
    }
    setTimeout(() => {
        if (!Number(value)) {
            callback(new Error('请输入正整数'))
        } else {
            const re = /^[0-9]*[1-9][0-9]*$/
            const rsCheck = re.test(value)
            if (!rsCheck) {
                callback(new Error('请输入正整数'))
            } else {
                callback()
            }
        }
    }, 1000)
}

// 验证是否是[0-1]的小数
export const isDecimal = (rule, value, callback) => {
    if (value === '' || value === undefined || value === null) {
        return callback(new Error('输入不可以为空'))
    }
    setTimeout(() => {
        if (!Number(value)) {
            callback(new Error('请输入[0,1]之间的数字'))
        } else {
            if (value < 0 || value > 1) {
                callback(new Error('请输入[0,1]之间的数字'))
            } else {
                callback()
            }
        }
    }, 100)
}

/* 小写字母*/
export const validateLowerCase = (str) => {
    const reg = /^[a-z]+$/
    return reg.test(str)
}

/* 大写字母*/
export const validateUpperCase = (str) => {
    const reg = /^[A-Z]+$/
    return reg.test(str)
}

/* 大小写字母*/
export const validatAlphabets = (str) => {
    const reg = /^[A-Za-z]+$/
    return reg.test(str)
}

// 校验个人证件类型
/* eslint-disable indent */
export const validCredNum = (type, credNum) => {
    let validFlag = true
    let msg = '证件号码格式有误'

    switch (type) {
        case '10': {
            // 身份证
            validFlag = validateSecIdCard(credNum)
            msg = '身份证格式有误'
            break
        }
        case '1': {
            // 户口簿
            validFlag = /^\d{9}$/.test(credNum)
            msg = '户口簿格式有误'
            break
        }
        case '2': {
            // 护照
            validFlag = /(^(14|15)\d{7})|(^[DEGPS]\d{7,8}$)/gi.test(credNum)
            msg = '护照格式有误'
            break
        }
        case '5': {
            /**
             * 港澳居民来往内地通行证，证件号的正则规则兼容以下三种类型：
             *  1）H/M + 10位阿拉伯数字
             *  2）C/M + 8位阿拉伯数字
             *  3）C + 1位英文字母 + 7位阿拉伯数字。第二位英文字母不能是I或O
             */
            validFlag = /^[HM][0-9]{10}$|^[CM][0-9]{8}$|^[C][A-HJ-NP-Z][0-9]{7}$/.test(credNum)
            msg = '港澳居民来往内地通行证格式有误'
            break
        }
        case '6': {
            /**
             * 台湾居民来往大陆通行证
             *  1）9位:L+8位阿拉伯数字
             */
            validFlag = /^\d{8}$/.test(credNum)
            msg = '台湾同胞来往内地通行证格式有误'
            break
        }
        case '8': {
            // 外国人居留证
            validFlag = /^[A-Z]{3}\d{6}(?:0[1-9]|1[021])(?:0[1-9]|[21]\d|3[10])\d{2}$/.test(credNum)
            msg = '外国人居留证格式有误'
            break
        }
        case '9': {
            // 警官证
            validFlag = /^[\u4E00-\u9FA5](字第)([0-9a-zA-Z]{4,8})(号?)$/.test(credNum)
            msg = '警官证格式有误'
            break
        }
        case 'A': {
            // 香港身份证
            validFlag =
                /^8[123]0000(?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3}[\dX]$/.test(
                    credNum
                )
            msg = '香港身份证格式有误'
            break
        }
        case 'B': {
            // 澳门身份证
            validFlag =
                /^8[123]0000(?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3}[\dX]$/.test(
                    credNum
                )
            msg = '澳门身份证格式有误'
            break
        }
        case 'C': {
            // 台湾身份证
            validFlag =
                /^8[123]0000(?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3}[\dX]$/.test(
                    credNum
                )
            msg = '台湾身份证格式有误'
            break
        }
        case 'X': {
            // 其他证件
            validFlag = true
            break
        }
        case '20': {
            // 军人身份证
            validFlag = /^[a-zA-Z0-9]{7,21}$/.test(credNum)
            msg = '军人身份证格式有误'
            break
        }
        default: {
            validFlag = true
        }
    }
    return {
        res: validFlag,
        msg
    }
}

/**
 * 充分考虑的情况下 校验身份证号
 * @param value
 * @returns
 */
export function validateSecIdCard(value) {
    if (!value) return true
    var iSum = 0
    var sId = value
    var aCity = {
        11: '北京',
        12: '天津',
        13: '河北',
        14: '山西',
        15: '内蒙',
        21: '辽宁',
        22: '吉林',
        23: '黑龙',
        31: '上海',
        32: '江苏',
        33: '浙江',
        34: '安徽',
        35: '福建',
        36: '江西',
        37: '山东',
        41: '河南',
        42: '湖北',
        43: '湖南',
        44: '广东',
        45: '广西',
        46: '海南',
        50: '重庆',
        51: '四川',
        52: '贵州',
        53: '云南',
        54: '西藏',
        61: '陕西',
        62: '甘肃',
        63: '青海',
        64: '宁夏',
        65: '新疆',
        71: '台湾',
        81: '香港',
        82: '澳门',
        83: '台湾',
        91: '国外'
    }

    if (
        !/^[1-9][0-9]\d{4}(?:19|20)\d{2}(?:0[1-9]|1[0-2])(?:0[1-9]|[12]\d|3[01])\d{3}[\dX]$/.test(
            sId
        )
    ) {
        return false
    }

    sId = sId.replace(/x$/i, 'a')
    // 非法地区
    if (aCity[parseInt(sId.substr(0, 2))] === null) {
        return false
    }
    var sBirthday =
        sId.substr(6, 4) + '-' + Number(sId.substr(10, 2)) + '-' + Number(sId.substr(12, 2))
    var d = new Date(sBirthday.replace(/-/g, '/'))
    // 非法生日
    if (sBirthday !== d.getFullYear() + '-' + (d.getMonth() + 1) + '-' + d.getDate()) {
        return false
    }
    for (let i = 17; i >= 0; i--) {
        iSum += (Math.pow(2, i) % 11) * parseInt(sId.charAt(17 - i), 11)
    }
    if (iSum % 11 !== 1) {
        return false
    }
    return true
}
